///************************************************************************
/// <copyrigth>2018-2019 Corporation.All Rights Reserved</copyrigth>
/// <author>tangyingzhong</author>
/// <contact>tangyz114987@outlook.com</contact>
/// <version>v1.0.0</version>
/// <describe>
/// Message queue for all the processes in one computer
///</describe>
/// <date>2019/7/16</date>
///***********************************************************************
#ifndef MESSAGEQUEUE_H
#define MESSAGEQUEUE_H

#include <string>
#include <iostream>
#include "boost/interprocess/ipc/message_queue.hpp"

namespace bip = boost::interprocess;

namespace SystemTool
{
	namespace Buffer
	{
		enum MQOpenMode
		{
			// Create only
			MQ_CREATE_ONLY = 0,

			// Open only 
			MQ_OPEN_ONLY
		};

		class MessageQueue
		{
		public:
			typedef void None;
			typedef void* Object;
			typedef bool Boolean;

		public:
			// Construct the MessageQueue
			MessageQueue();

			// Detructe the MessageQueue
			~MessageQueue();

		private:
			// Forbid the object copying
			MessageQueue(const MessageQueue& other) {	}

			// Forbid the object copying
			MessageQueue& operator=(const MessageQueue& other) { return *this; }

		public:
			// Configure the queue
			None Configure(const std::string strQueueName, 
				const int32_t iQueueSize,
				const int32_t iElementSize);

			// Is the shared queue opened or not
			Boolean IsOpen();

			// Open the managed queue
			Boolean Open(MQOpenMode eOpenMode);

			// Close the managed queue(note: if you destory the share queue, you must open it with create mode at next time)
			Boolean Close();

			// Blocking read the common queue.(note: you shouln't use std::string but char*)
			Boolean Read(void* pData);

			// Blocking write to the common queue
			Boolean Write(void* pData);

		private:
			// Initialize the shared queue
			None Initialize();

			// Destory the shared queue
			None Destory();

			// Destory the share queue
			Boolean DestoryQueue();

		private:
			// Get the managed queue
			inline bip::message_queue* GetManagedQueue() const
			{
				return m_pMsgQueue;
			}

			// Set the managed queue
			inline None SetManagedQueue(bip::message_queue* pMsgQueue)
			{
				m_pMsgQueue = pMsgQueue;
			}

			// Get the Name
			inline std::string GetQueueName() const
			{
				return m_strQueueName;
			}

			// Set the Name
			inline None SetQueueName(std::string strQueueName)
			{
				m_strQueueName = strQueueName;
			}

			// Get the queue size
			inline int32_t GetQueueSize() const
			{
				return m_iQueueSize;
			}

			// Set the queue size
			inline None SetQueueSize(int32_t iQueueSize)
			{
				m_iQueueSize = iQueueSize;
			}

			// Get the element size
			inline int32_t GetElementSize() const
			{
				return m_iElementSize;
			}

			// Set the element sizee
			inline None SetElementSize(int32_t iElementSize)
			{
				m_iElementSize = iElementSize;
			}

			// Get the disposed
			inline Boolean GetDisposed() const
			{
				return m_Disposed;
			}

			// Set the disposed	
			inline None SetDisposed(Boolean bDisposed)
			{
				m_Disposed = bDisposed;
			}

		private:
			// Message queue in the processes
			bip::message_queue* m_pMsgQueue;

			// The name of the queue
			std::string m_strQueueName;

			// The size of the sheared queue
			int32_t m_iQueueSize;

			// Every element's size
			int32_t m_iElementSize;

			// Disposed status
			Boolean m_Disposed;
		};
	}
}

#endif // MESSAGEQUEUE_H
